package com.healthybear.demo.languagechange

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

/**
 * Abstract base activity that provides consistent language management behavior
 * across all activities in the application.
 * 
 * Requirements addressed:
 * - 6.1: Apply correct language configuration in attachBaseContext
 * - 6.2: Check if language has changed and restart if necessary in onResume
 * - 6.3: Provide smooth transition animations when restarting
 * - 6.4: Preserve current navigation state when activities are restarted
 */
abstract class BaseActivity : AppCompatActivity() {
    
    private var currentLanguage: String? = null
    
    /**
     * Requirement 6.1: Apply the correct language configuration in attachBaseContext
     * 
     * This method is called before onCreate() and ensures that the activity
     * uses the correct language configuration from the start.
     */
    override fun attachBaseContext(newBase: Context) {
        try {
            val contextWithLanguage = LanguageUtils.attachBaseContext(newBase)
            super.attachBaseContext(contextWithLanguage)
        } catch (e: Exception) {
            // If language context attachment fails, use the original context
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Failed to attach language context, using default",
                e,
                mapOf("activityClass" to this::class.java.simpleName)
            )
            super.attachBaseContext(newBase)
        }
    }
    
    /**
     * Initialize current language tracking
     * 
     * This method sets up the initial language state and ensures proper
     * language configuration is applied when the activity is created.
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        try {
            // Initialize current language tracking
            currentLanguage = LanguageUtils.getLanguagePreference(this)
            
            // Validate the current language
            val validationResult = ErrorHandler.validateLanguageCode(currentLanguage ?: "")
            if (validationResult is ErrorHandler.ValidationResult.Invalid) {
                ErrorHandler.logErrorWithContext(
                    "BaseActivity",
                    "Invalid language preference detected, using fallback",
                    context = mapOf(
                        "invalidLanguage" to (currentLanguage ?: "null"),
                        "reason" to validationResult.reason
                    )
                )
                currentLanguage = LanguageUtils.SupportedLanguage.ENGLISH.code
            }
            
            // Log the current language for debugging
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Activity created successfully",
                context = mapOf(
                    "language" to (currentLanguage ?: "unknown"),
                    "activityClass" to this::class.java.simpleName
                )
            )
            
        } catch (e: Exception) {
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Error during activity creation",
                e,
                mapOf("activityClass" to this::class.java.simpleName)
            )
            // Set fallback language
            currentLanguage = LanguageUtils.SupportedLanguage.ENGLISH.code
        }
    }
    
    /**
     * Requirement 6.2: Check if language has changed and restart if necessary in onResume
     * 
     * This method detects language changes that might have occurred while the activity
     * was paused (e.g., from system settings or other activities) and restarts the
     * activity if needed to apply the new language.
     */
    override fun onResume() {
        super.onResume()
        
        try {
            val savedLanguage = LanguageUtils.getLanguagePreference(this)
            
            // Check if language has changed since activity was created/last resumed
            if (currentLanguage != null && currentLanguage != savedLanguage) {
                ErrorHandler.logErrorWithContext(
                    "BaseActivity",
                    "Language change detected, restarting activity",
                    context = mapOf(
                        "previousLanguage" to (currentLanguage ?: "unknown"),
                        "newLanguage" to savedLanguage,
                        "activityClass" to this::class.java.simpleName
                    )
                )
                
                // Update current language before restart
                currentLanguage = savedLanguage
                
                // Restart activity to apply new language
                restartActivity()
            } else if (currentLanguage == null) {
                // First time resume, set current language
                currentLanguage = savedLanguage
                ErrorHandler.logErrorWithContext(
                    "BaseActivity",
                    "First resume, setting current language",
                    context = mapOf("language" to savedLanguage)
                )
            }
            
            // For Method 3 (System Settings), check if system language changed
            if (getImplementationType() == LanguageUtils.ImplementationType.SYSTEM_SETTINGS) {
                try {
                    if (LanguageUtils.hasSystemLanguageChanged(this)) {
                        ErrorHandler.logErrorWithContext(
                            "BaseActivity",
                            "System language changed, restarting activity",
                            context = mapOf("implementationType" to "SYSTEM_SETTINGS")
                        )
                        restartActivity()
                    }
                } catch (e: Exception) {
                    ErrorHandler.logErrorWithContext(
                        "BaseActivity",
                        "Error checking system language change",
                        e,
                        mapOf("implementationType" to "SYSTEM_SETTINGS")
                    )
                }
            }
            
        } catch (e: Exception) {
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Error during onResume language check",
                e,
                mapOf("activityClass" to this::class.java.simpleName)
            )
        }
    }
    
    /**
     * Requirement 6.3: Provide smooth transition animations when restarting
     * Requirement 6.4: Preserve current navigation state when activities are restarted
     * 
     * This method handles activity restart with smooth animations and state preservation.
     * It ensures that the user experience is seamless when language changes require
     * activity recreation.
     */
    fun restartActivity() {
        try {
            // Call lifecycle callback before restart
            onLanguageChangeDestroy()
            
            // Get the current intent to preserve navigation state
            val currentIntent = intent
            
            // Preserve any extra data that might be important for state
            val extras = currentIntent.extras
            
            // Create new intent with preserved state
            val restartIntent = Intent(this, this::class.java).apply {
                // Copy all extras to preserve state
                if (extras != null) {
                    putExtras(extras)
                }
                
                // Add flags to ensure proper activity lifecycle
                flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
            }
            
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Restarting activity for language change",
                context = mapOf(
                    "activityClass" to this::class.java.simpleName,
                    "hasExtras" to (extras != null),
                    "implementationType" to getImplementationType().name
                )
            )
            
            // Finish current activity
            finish()
            
            // Start new instance with preserved state
            startActivity(restartIntent)
            
            // Apply smooth transition animations
            overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
            
        } catch (e: Exception) {
            ErrorHandler.logErrorWithContext(
                "BaseActivity",
                "Failed to restart activity smoothly, trying fallback",
                e,
                mapOf("activityClass" to this::class.java.simpleName)
            )
            
            // Fallback to simple restart if smooth restart fails
            try {
                recreate()
                ErrorHandler.logErrorWithContext(
                    "BaseActivity",
                    "Successfully used recreate() as fallback",
                    context = mapOf("activityClass" to this::class.java.simpleName)
                )
            } catch (recreateException: Exception) {
                ErrorHandler.handleLanguageSwitchError(
                    this,
                    recreateException,
                    ErrorHandler.ErrorType.UNKNOWN_ERROR
                )
            }
        }
    }
    
    /**
     * Abstract method that must be implemented by concrete activities
     * to specify which language switching implementation they use.
     * 
     * This allows the BaseActivity to provide implementation-specific
     * behavior when needed (e.g., system language change detection).
     * 
     * @return The implementation type used by this activity
     */
    protected abstract fun getImplementationType(): LanguageUtils.ImplementationType
    
    /**
     * Utility method to get the current language preference
     * 
     * @return The current language code
     */
    protected fun getCurrentLanguage(): String {
        return currentLanguage ?: LanguageUtils.getLanguagePreference(this)
    }
    
    /**
     * Utility method to check if the activity needs restart for language changes
     * based on the implementation type.
     * 
     * @return true if restart is needed, false otherwise
     */
    protected fun needsRestartForLanguageChange(): Boolean {
        return when (getImplementationType()) {
            LanguageUtils.ImplementationType.APP_COMPAT_DELEGATE -> false // Auto-applies
            LanguageUtils.ImplementationType.CONFIGURATION_UPDATE -> true  // Needs restart
            LanguageUtils.ImplementationType.SYSTEM_SETTINGS -> false     // System handles it
        }
    }
    
    /**
     * Called when the activity is being destroyed due to language change
     * Subclasses can override this to perform cleanup before restart
     */
    protected open fun onLanguageChangeDestroy() {
        // Default implementation does nothing
        // Subclasses can override to save state or perform cleanup
    }
    
    override fun onDestroy() {
        // Check if destruction is due to language change
        if (isFinishing && currentLanguage != LanguageUtils.getLanguagePreference(this)) {
            onLanguageChangeDestroy()
        }
        
        super.onDestroy()
    }
}